package com.disease.api.service.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.disease.api.service.entity.HospitalInfo;
import com.disease.api.service.entity.eumns.CodeEnum;
import com.disease.api.service.mapper.HospitalInfoMapper;
import com.disease.api.service.model.ResponseResult;
import com.disease.api.service.model.request.DeathCardReportRequest;
import com.disease.api.service.model.response.RepeatCardNoResponse;
import com.disease.api.service.model.response.thirdParty.DeathCardApplyResponse;
import com.disease.api.service.model.response.thirdParty.DeathCardResponse;
import com.disease.api.service.model.response.thirdParty.OAuthTokenResponse;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class DeathCardReportService {

    private OkHttpClient httpClient= new OkHttpClient().newBuilder().build();

    @Value("${deathSystem.host}")
    private String host;

    @Value("${deathSystem.authorization}")
    private String authorization;

    @Autowired
    private HospitalInfoMapper hospitalInfoMapper;

    public HospitalInfo hospitalInfo;

    private static final String DATA="data";

    @Autowired
    private CommonService commonService;

    @Value("${deathSystem.url.token_url}")
    private  String tokenUrl;

    @Value("${deathSystem.url.death_report_first_step_url}")
    private  String deathReportFirstStepUrl;

    @Value("${deathSystem.url.death_report_second_step_url}")
    private  String deatReportSecondStepUrl;

    @Value("${deathSystem.url.death_card_apply_url}")
    private  String deathCardApplyUrl;

    @Value("${deathSystem.url.death_card_status_url}")
    private  String deathCardStatusUrl;

    @Value("${deathSystem.url.cancel_death_card_Url}")
    private String cancelDeathCardNoUrl;

    @Value("${deathSystem.url.find_repeat_card_Url}")
    private String findRepeatCardNoUrl;

    @PostConstruct
    public void init() {
        hospitalInfo=hospitalInfoMapper.selectOne();
    }

    public void updateHospitalInfo(HospitalInfo hospitalInfo) {
        this.hospitalInfo = hospitalInfo;
    }

    /**
     * 获取授权token
     * @return
     */
    public OAuthTokenResponse getOauthToken(){
        OAuthTokenResponse oAuthTokenResponse=new OAuthTokenResponse();
        //判断死因系统appid和appsecurity是否为空
        if(!Optional.ofNullable(hospitalInfo.getDeathSystemAppid()).isPresent()||!Optional.ofNullable(hospitalInfo.getDeathSystemAppsecurity()).isPresent()){
            return oAuthTokenResponse;
        }
        MediaType mediaType=MediaType.parse("application/x-www-form-urlencoded");
        RequestBody requestBody=RequestBody.create(mediaType, "username="+hospitalInfo.getDeathSystemAppid()+"&password="+hospitalInfo.getDeathSystemAppsecurity()+"&loginType=3");
        Request request=new Request.Builder()
                .url(host+tokenUrl)
                .method("POST",requestBody)
                .addHeader("Authorization","Basic "+ authorization)
                .addHeader("Content-Type","application/x-www-form-urlencoded")
                .build();
        try {
            Response executeResponse = httpClient.newCall(request).execute();
            String responseResult = executeResponse.body().string();
            log.info("getOauthToken response:{}",responseResult);
            oAuthTokenResponse =JSONObject.parseObject(responseResult, OAuthTokenResponse.class);
        }catch (Exception e){
            log.error("getOauthToken error:{}",e.getMessage());
        }
        return oAuthTokenResponse;
    }

    /**
     * 获取 deathCardNum
     * @return
     */
    public ResponseResult<DeathCardApplyResponse> generateDeathCardNum(int applyCount){
        String generateDeathCardUrl=host+deathCardApplyUrl;
        String requestBody=JSONObject.toJSONString(ImmutableMap.of("applyCount", applyCount, "loginName", hospitalInfo.getDeathSystemLoginName()));
        try {
            Response response = doPostHttpRequest(getOauthToken().getAccess_token(), generateDeathCardUrl, requestBody);
            String result=response.body().string();
            log.info("generateDeathCardNum response:{}",result);
            ResponseResult responseResult = JSONObject.parseObject(result, new TypeReference<ResponseResult<DeathCardApplyResponse>>(){});
            return   responseResult;
        } catch (IOException e) {
            return ResponseResult.fail("获取死亡卡失败");
        }
    };

    /**
     * 获取 deathCardNum 默认生成一张
     * @return
     */
    public ResponseResult<DeathCardApplyResponse> generateDeathCardNum(){
        return generateDeathCardNum(1);
    };

    /**
     *  DeathCardReport 上报第一联死亡信息
     * @param deathCardReportRequest
     */
    public ResponseResult reportFirstDeathInfo(DeathCardReportRequest deathCardReportRequest){
        String cardNo = deathCardReportRequest.getCardNo();
        deathCardReportRequest.setLoginName(hospitalInfo.getDeathSystemLoginName());
        String generateDeathCardUrl=host+deathReportFirstStepUrl;
        log.info("序列:{},死亡卡号:{},reportFirstDeathInfo:{}",deathCardReportRequest.getSerialNumber(),cardNo,JSONObject.toJSONString(deathCardReportRequest));
        try {
            Response response = doPostHttpRequest(getOauthToken().getAccess_token(), generateDeathCardUrl, JSONObject.toJSONString(deathCardReportRequest));
            String result=response.body().string();
            log.info("序列:{},死亡卡号:{},reportFirstDeathInfo response:{}",deathCardReportRequest.getSerialNumber(),cardNo,result);
            ResponseResult responseResult = JSONObject.parseObject(result, new TypeReference<ResponseResult>(){});
            if(responseResult.isSuccess()){
                if(responseResult.isSuccess()){
                    return ResponseResult.success(cardNo);
                }else {
                    return responseResult;
                }
            }else{
                return responseResult;
            }
        } catch (IOException e) {
            log.error("序列:{},死亡卡号:{},reportFirstDeathInfo error:{}",deathCardReportRequest.getSerialNumber(),deathCardReportRequest.getCardNo(),e.getMessage());
            return ResponseResult.fail(e.getMessage());
        }
    }

    /**
     *  DeathCardReport 上报第二、三联死亡信息
     * @param deathCardReportRequest
     */
    public ResponseResult reportSecondDeathInfo(DeathCardReportRequest deathCardReportRequest){
        String generateDeathCardUrl=host+deatReportSecondStepUrl;
        log.info("reportSecondDeathInfo:{}",JSONObject.toJSONString(deathCardReportRequest));
        try {
            Response response = doPostHttpRequest(getOauthToken().getAccess_token(), generateDeathCardUrl, JSONObject.toJSONString(deathCardReportRequest));
            String result=response.body().string();
            log.info("reportSecondDeathInfo response:{}",result);
            return JSONObject.parseObject(result,ResponseResult.class);
        } catch (IOException e) {
            log.error("reportSecondDeathInfo error:{}",e.getMessage());
            return ResponseResult.fail(e.getMessage());
        }
    }

    /**
     *  cancelDeathCard 注销死亡卡号
     * @param cardNo
     */
    public ResponseResult cancelDeathCard(String cardNo){
        String generateDeathCardUrl=host+cancelDeathCardNoUrl;
        String requestBody=JSONObject.toJSONString(ImmutableMap.of("cardNo", cardNo, "uniqueIdentifier",commonService.generatorUniqueIdentifier(hospitalInfo.getOrgCode()),"opinion","错误输入","loginName", hospitalInfo.getDeathSystemLoginName()));
        try {
            Response response = doPostHttpRequest(getOauthToken().getAccess_token(), generateDeathCardUrl, requestBody);
            String result=response.body().string();
            log.info("reportSecondDeathInfo response:{}",result);
            return JSONObject.parseObject(result,ResponseResult.class);
        } catch (IOException e) {
            log.error("reportSecondDeathInfo error:{}",e.getMessage());
            return ResponseResult.fail(e.getMessage());
        }
    }

    /**
     *  findRepeatCardNo 注销死亡卡号
     * @param idCard
     */
    public ResponseResult findRepeatCardNo(String idCard){
        String generateDeathCardUrl=host+findRepeatCardNoUrl;
        String requestBody=JSONObject.toJSONString(ImmutableMap.of("idCardCode", idCard));
        try {
            Response response = doPostHttpRequest(getOauthToken().getAccess_token(), generateDeathCardUrl, requestBody);
            String result=response.body().string();
            log.info("findRepeatCardNo:{} response:{}",idCard,result);
            ResponseResult responseResult = JSONObject.parseObject(result, ResponseResult.class);
            if(responseResult.getData() instanceof JSONArray){
                RepeatCardNoResponse repeatCardNoResponse = JSONObject.parseArray(JSONObject.toJSONString(responseResult.getData()), RepeatCardNoResponse.class).get(0);
                repeatCardNoResponse.setMessage("证件号码"+idCard+"已报送死亡卡");
                return ResponseResult.success(repeatCardNoResponse);
            }else {
                return responseResult;
            }
        } catch (IOException e) {
            log.error("findRepeatCardNo:{} error:{}",idCard,e.getMessage());
            return ResponseResult.fail(e.getMessage());
        }

    }

    private Response doPostHttpRequest(String authorization,String url, String body) throws IOException {
        log.info("doPostHttpRequest authorization:{}, url:{},body:{}",authorization,url,body);
        MediaType mediaType=MediaType.parse("application/json");
        RequestBody requestBody=RequestBody.create(mediaType, body);
        Request request=new Request.Builder()
                .url(url)
                .method("POST",requestBody)
                .addHeader("Authorization","Bearer "+ authorization)
                .addHeader("Content-Type","application/json")
                .build();
        return httpClient.newCall(request).execute();
    }

    /**
     * 查询死亡卡状态
     * @param cardNo
     * @return
     */
    public ResponseResult queryDeathCardStatus(String cardNo){
        String queryDeathCardStatusUrl=host+deathCardStatusUrl;
        String requestBody=JSONObject.toJSONString(ImmutableMap.of("loginName", hospitalInfo.getDeathSystemLoginName(), "cardNo", cardNo));
        try {
            Response  response = doPostHttpRequest(getOauthToken().getAccess_token(), queryDeathCardStatusUrl, requestBody);
            String result=response.body().string();
            log.info("死亡卡号:{},queryDeathCardStatus response:{}",cardNo,result);
            return JSONObject.parseObject(result, ResponseResult.class);
        } catch (IOException e) {
            log.error("死亡卡号:{},reportSecondDeathInfo error:{}",cardNo,e.getMessage());
            return ResponseResult.fail(e.getMessage());
        }

    }

}
